<?php
/**
 * Pipahr
 *
 * @author Wei Ma
 * @copyright 2013 pipahr.com
 * 
 * @since   3.0
 */

JTable::addIncludePath(JPATH_ADMINISTRATOR.'/components/com_puser/tables');
JTable::addIncludePath(JPATH_ADMINISTRATOR.'/components/com_jobs/tables');
JTable::addIncludePath(JPATH_ADMINISTRATOR.'/components/com_persontest/tables');

/**
 * Registration controller class for Users.
 */
class PPersontestModelPersontest extends JModelLegacy
{
   /**
    * Get some useful info for persontest
    * 
    * @param   integer  $job_id  Jobposition id
    * @param   integer  $sheetid    Sheet id
    * @return  object  Persontest info object
    * 
    * @since   3.0
    */
   public function getPersontestInfo($jobid,$sheetid) {
      if (empty($jobid) && empty($sheetid))
         return null;
      $db = PFactory::getDbo();
      if(empty($jobid) && !empty($sheetid)){
         $query = "SELECT id AS sheetid, title AS sheettitle, alias AS sheetalias, topwords, description, totaltime, layout, questioncount AS qcount
                 FROM #__persontest_sheet
                  WHERE published=1  AND id=".intval($sheetid);
      }else{
         $query = "SELECT je.comp_name, pj.jobid, pj.sheetid, ps.title AS sheettitle, ps.alias AS sheetalias, ps.topwords, ps.description, ps.totaltime, ps.layout, ps.questioncount AS qcount FROM #__persontest_sheet AS ps 
                   LEFT JOIN #__persontest_jobsheet AS pj ON pj.sheetid=ps.id 
                   LEFT JOIN #__jobs_job AS jj ON jj.id=pj.jobid 
                   LEFT JOIN #__jobs_employer AS je ON je.user_id = jj.employer_id 
                   WHERE ps.published=1 AND jj.is_active='y' AND pj.jobid=".intval($jobid);
      }
      $db->setQuery($query);
      $persontestInfo = $db->loadObject();
      
      $pagesize = 5;
      $pagecount = ceil($persontestInfo->qcount/$pagesize);
      
      $persontestInfo->pagecount = $pagecount;
      return $persontestInfo;
   }
   
   /**
    * Get all questions of persontest sheet which bind to jobposition
    *
    * @param   integer  $jobid      Jobposition id
    * @param   integer  $sheetid    Sheet id
    * @param   integer  $getAnswer  Want answers too?
    * @param   integer  $start      Sql start
    * @param   integer  $limit      Sql limit
    * @return  array  Persontest sheet questions array list
    *
    * @since   3.0
    */
   public function getPersontestQuestions($jobid,$sheetid,$getAnswer=true, $start=0,$limit=10) {
      if (empty($jobid) && empty($sheetid))
         return null;
      $db = PFactory::getDbo();
      if(empty($jobid) && !empty($sheetid)){
         $by = $sheetid;
      }else{
         $by = '(SELECT sheetid FROM #__persontest_jobsheet WHERE jobid='.intval($jobid).')';
      }

      if ($getAnswer) {
         $select = " pq.id, pqd.question, pqd.answer ";
      } else {
         $select = " pq.id, pqd.question, pqd.answer AS options ";
      }

      $query = 'SELECT '.$select.'
               FROM #__persontest_question AS pq
               LEFT JOIN #__persontest_question_details AS pqd ON pqd.questionid=pq.id
               WHERE pq.sheetid='.$by.'
               ORDER BY pq.id ASC';
      if ($getAnswer) {
         $db->setQuery($query);
      } else {
         $db->setQuery($query, $start, $limit);
      }
      $questions = $db->loadObjectList();

      foreach ($questions as $k => $q) {
         if ($getAnswer) {
            if (isset($q->answer)) {
               $q->answer = json_decode($q->answer);
            }
         } else {
            if (isset($q->options)) {
               $q->options = json_decode($q->options);
               $options = array();
               foreach ($q->options as $kk => $cc) {
                  if (!empty($cc) && isset($cc->choice)) {
                     array_push($options, $cc->choice);
                  }
               }
               $q->options = $options;
            }
         }
      }
      
      return $questions;
   }

   /**
    * Check if user has delivered resume to this job
    *
    * @param   integer  $job_id  Jobposition id
    * @param   integer  $sheetid  Sheet id
    * @return  boolean  If delivered, return true, else false
    *
    * @since   3.0
    */
   public function hasDelivered($jobid,$sheetid) {
      if (empty($jobid) && empty($sheetid))
         return false;
      $db = PFactory::getDbo();
      $user = PFactory::getUser();
      if(empty($jobid) && !empty($sheetid)){
         $by = "";
      }else{
         $by = "AND hj.job_id =".intval($jobid);
      }
      $query = "SELECT COUNT(*) FROM *PREFIX*hr_jobseeker AS hj
                LEFT JOIN #__users AS u ON u.email=hj.email
                WHERE u.id=".$user->id." ".$by;
      $db->setQuery(PUtil::replaceOCPrefix($query));
      $result = $db->loadResult();
      if ($result) {
         return true;
      } else {
         return false;
      }
   }

   /**
    * Check if user has done the persontest before
    * 
    * @param   integer  $sheetid  sheet id
    * @return  boolean  If done, return true, else false
    * 
    * @since   3.0
    */
   public function hasDone($sheetid) {
      if (empty($sheetid))
         return false;
      $db = PFactory::getDbo();
      $user = PFactory::getUser();
      $query = "SELECT TIMESTAMPDIFF(day, end_time, UTC_TIMESTAMP()) FROM #__persontest_result WHERE user_id=".$user->id." AND sheetid=".intval($sheetid);
      $db->setQuery($query);
      $result = $db->loadResult();
      if(is_numeric($result) && $result<90){
         return true;
      }else{
         return false;
      }
   }

   /**
    * Save persontest answers
    * @param  bool  $is_mobile Set true if called by mobile api
    * @return  boolean
    * @since   3.0
    */
   public function save($is_mobile=false) {
      $post = JRequest::get('post');

      if (!$is_mobile && !PSession::checkToken('post')) {
         $this->setError('登录已失效，请重新登录！');
         return false;
      }

      if (empty($post)) {
         $this->setErrorCode(10002);
         $this->setError('网络异常，请重试！');
         return false;
      }

      $db = PFactory::getDbo();
      $user = PFactory::getUser();
      
      $jobid      = JRequest::getInt('jobid', 0);
      $sheetid    = JRequest::getInt('sheetid', 0);
      //if jobid and sheetid both donn't get,return
      if(empty($jobid)&&empty($sheetid)){
         $this->setErrorCode(10002);
         $this->setError('系统错误，请重试！');
         return;
      }

      if($jobid){
         $sheetid=$this->getSheetidByjobid($jobid);
      }

      $sheetalias = JRequest::getString('sheetalias', null);
      $typefrom = JRequest::getString('typefrom', null);
      if(empty($typefrom)){
         if (empty($jobid) || empty($sheetid) || empty($sheetalias)) {
            $this->setErrorCode(10002);
            $this->setError('网络异常，请重试！');
            return false;
         }
      }else{
         if (empty($sheetid) || empty($sheetalias)) {
            $this->setErrorCode(10002);
            $this->setError('网络异常，请重试！');
            return false;
         }
      }

      if ($this->hasDone($sheetid)) {
         $this->setErrorCode(50002);
         $this->setError('您已参加过性格评测！');
         return false;
      }

      if ($is_mobile) {
         $answers = isset($post['answers']) ? json_decode($post['answers'],true) : array();
      } else {
         $answers = isset($post['panswers']) ? $post['panswers'] : array();
      }
      if (empty($answers)) {
         $this->setErrorCode(50006);
         $this->setError('您还没有填写答卷，提交失败！');
         return false;
      }

      // update persontest sheet numtesters
      if(!empty($jobid)){
         $query = 'UPDATE #__persontest_jobsheet SET numtesters=numtesters+1 WHERE jobid='.intval($jobid).' AND sheetid='.intval($sheetid);
         $db->setQuery($query);
         $db->execute();
      }

      // update persontest sheet numtesters
      $query = 'UPDATE #__persontest_sheet SET hits=hits+1 WHERE id='.intval($sheetid);
      $db->setQuery($query);
      $db->execute();
      
      // get all persontest questions answer
      $persontestQuestions = $this->getPersontestQuestions($jobid,$sheetid);

      // rearrange the answer details
      $persontestQuestionsDetails = array();
      foreach ($persontestQuestions as $persontestQuestion) {
         $persontestQuestionsDetails[$persontestQuestion->id] = $persontestQuestion->answer;
      }

      // build persontest result details, $key is pattern and $value is pattern count or score
      $resultDetails = array();
      if($sheetalias=='MBTI'){
         $resultDetails=array('E'=>0,'F'=>0,'I'=>0,'J'=>0,'N'=>0,'P'=>0,'S'=>0,'T'=>0);
      }

      foreach ($persontestQuestionsDetails as $qid => $persontestQuestionDetails) {
         if (isset($answers[$qid])) {
            $key = $answers[$qid];
            $panswer = isset($persontestQuestionDetails[$key]) ? $persontestQuestionDetails[$key] : "";
            $pscore = isset($panswer->score) ? $panswer->score : 0;
            $ppattern = isset($panswer->pattern) ? $panswer->pattern : 'SCORE';

            if ($ppattern != 'NULL') {
               if (array_key_exists($ppattern, $resultDetails)) {
                  $resultDetails[$ppattern] += $pscore;
               } else {
                  $resultDetails[$ppattern] = $pscore;
               }
            }
         }
      }

      // build persontest result
      $result = '';
      $resultData = array();
      arsort($resultDetails, SORT_NUMERIC);
      $resultKeys = array_keys($resultDetails);
      switch ($sheetalias) {
         default:
         case 'ENNEAGRAM':
            $tmpPattern = $resultKeys[0];
            if ($resultDetails[$tmpPattern] > 0) {
               $result = $resultKeys[0];
            }
            break;
         case 'MBTI':
            $result .= ($resultDetails['E'] > $resultDetails['I'] ? 'E' : 'I' );
            $result .= ($resultDetails['S'] > $resultDetails['N'] ? 'S' : 'N' );
            $result .= ($resultDetails['T'] > $resultDetails['F'] ? 'T' : 'F' );
            $result .= ($resultDetails['J'] > $resultDetails['P'] ? 'J' : 'P' );
            break;
         case 'HOLLAND':
            if (array_key_exists(0, $resultKeys)) {
               $result .= $resultKeys[0];
            }
            if (array_key_exists(0, $resultKeys)) {
               $result .= $resultKeys[1];
            }
            if (array_key_exists(0, $resultKeys)) {
               $result .= $resultKeys[2];
            }
            break;
         case 'COMMUNICATE':
            $c_score = isset($resultDetails['SCORE']) ? $resultDetails['SCORE'] : 0;
            if ($c_score >= 0 && $c_score <= 20) {
               $result = 'COMMUNICATE_POOR';
            } elseif ($c_score <= 30) {
               $result = 'COMMUNICATE_GOOD';
            } else {
               $result = 'COMMUNICATE_EXPERT';
            }
            break;
         case 'EQ':
            $e_score = isset($resultDetails['SCORE']) ? $resultDetails['SCORE'] : 0;
            if ($e_score >= 0 && $e_score < 45) {
               $result = 'EQ_POOR';
            } elseif ($e_score < 65) {
               $result = 'EQ_GOOD';
            } elseif ($e_score < 80) {
               $result = 'EQ_GREAT';
            } else {
               $result = 'EQ_EXPERT';
            }
            break;
         case 'STRESS':
            $s_score = isset($resultDetails['SCORE']) ? $resultDetails['SCORE'] : 0;
            if ($s_score >= 0 && $s_score <= 2) {
               $result = 'STRESS_NO';
            } elseif ($s_score <= 7) {
               $result = 'STRESS_NERVOUS';
            } elseif ($s_score <= 12) {
               $result = 'STRESS_REBEL';
            } else {
               $result = 'STRESS_LOSER';
            }
            break;
      }

      $app = PFactory::getApplication();
      $start_time = $app->getUserState('persontest_start_time_' . $sheetid, null);
      if(empty($start_time)) {
         $start_time = PFactory::getDate()->toSql();
      }
      $resultData = array('alias' => $sheetalias, 'result' => $result, 'details' => $resultDetails);
      $end_time = PFactory::getDate()->toSql();
      $query = "INSERT INTO #__persontest_result (`user_id`, `sheetid`, `result`, `start_time`, `end_time`) VALUES
                ('".$user->id."', '".intval($sheetid)."', ".$db->quote(json_encode($resultData)).", ".$db->quote($start_time).", ".$db->quote($end_time).")
                 ON DUPLICATE KEY UPDATE result=".$db->quote(json_encode($resultData)).",start_time=".$db->quote($start_time).",end_time=".$db->quote($end_time);
      $db->setQuery($query);
      if (!$db->execute()) {
         $this->setError('网络异常，请重试！');
         return false;
      }
      CacheHelper::triggerRemove($user->id, array('#__persontest_result'));

      // stay on master: read-your-write 
      $db->stayOnMaster(); 
      //get all jobid base on persontest_result's sheetid,then update jobseeker's online_interview_progress
      $jobids=$this->getAllJobids($user->id,$sheetid);
      if($jobids){
          PInterviewHelper::updateInterviewProgress('persontest', $user->id, $jobids);
      }

      // leave on master now 
      $db->leaveOnMaster();
      return true;
   }

   public function getAllJobids($userid,$sheetid) {
      $db=PFactory::getDbo();
      $query="SELECT ohj.job_id as jobid
         FROM *PREFIX*hr_jobseeker AS ohj
         LEFT JOIN #__users AS ju ON ju.email=ohj.email
         LEFT JOIN #__persontest_jobsheet AS jpj ON jpj.jobid = ohj.job_id
         WHERE jpj.sheetid=".intval($sheetid)." AND ju.id=".intval($userid);
      $db->setQuery(PUtil::replaceOCPrefix($query));
      return $db->loadAssocList(null,'jobid');
   }

   /**
    * Get jobposition info which persontest belong to
    *
    * @param   integer  $job_id  Jobposition id
    * @return  object  Jobposition infomation
    *
    * @since   3.0
    */
   public function getJobposInfo($jobid) {
      if (empty($jobid))
         return null;
      $db = PFactory::getDbo();
      $query = "SELECT je.comp_name,je.validated,jjc.category,jct.comp_type,jcst.size_type,c.state AS cstate,c.city AS ccity,je.contact_name,jj.email,jj.phone,c.address,jj.job_title,jj.state,jj.city,jst.salary_type,jje.exp_name,jj.num_needed,jj.employer_id,c.avatar,c.avatarapproved, jid.industry, je.sub_domain
         FROM #__jobs_job jj
         LEFT JOIN #__jobs_employer je ON jj.employer_id = je.user_id
         LEFT JOIN #__comprofiler c ON jj.employer_id = c.user_id
         LEFT JOIN #__jobs_job_categ jjc ON jj.id_job_spec_categ = jjc.id
         LEFT JOIN #__jobs_comp_type jct ON je.id_comp_type = jct.id
         LEFT JOIN #__jobs_comp_size_type jcst ON je.id_size_type = jcst.id
         LEFT JOIN #__jobs_salary_type jst ON jj.id_salary_type = jst.id
         LEFT JOIN #__jobs_job_exp jje ON jj.id_job_exp = jje.id
         LEFT JOIN #__jobs_industry jid ON je.id_industry = jid.id
         WHERE jj.id=".intval($jobid)." AND jj.is_active = 'y'";
      $db->setQuery($query);
      return $db->loadObject();
   }
   
   public function getSheetidByjobid($jobid){
      $db = PFactory::getDbo();
      $query='SELECT sheetid FROM #__persontest_jobsheet WHERE jobid='.intval($jobid);
      $db->setQuery($query);
      return $db->loadResult();
   }
}
